﻿using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;
using MongoDB.Driver;
using MongoDB.Driver.Builders;
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;

namespace AliIotAmqpWorker.Common
{
    /// <summary>
    /// MongoDB数据库
    /// </summary>
    public class MongoDBHelper
    {
        private readonly string connectionstring = "mongodb://root:-C2uVB_qVr7k-9PMCKcafdZ4KWf5fKngOc3-Er9Susohgny_vG@172.21.168.38:27017";
        private readonly string databaseName = "mqtt-server-for-webaccess";
        private readonly IMongoDatabase _database = null;

        public MongoDBHelper()
        {
            var client = new MongoClient(connectionstring);
            if (client != null)
            {
                _database = client.GetDatabase(databaseName);
            }
        }

        public MongoDBHelper(string ConnectionString, string DatabaseName)
        {
            connectionstring = ConnectionString;
            databaseName = DatabaseName;
            var client = new MongoClient(connectionstring);
            if (client != null)
            {
                _database = client.GetDatabase(databaseName);
            }
        }

        #region SELECT
        /// <summary>
        /// 根据查询条件，获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="TableName">数据表名称</param>
        /// <param name="conditions">查询条件，查询条件编写按照Lamada表达式形式</param>
        /// <returns></returns>
        public List<T> GetList<T>(string TableName, Expression<Func<T, bool>> conditions = null)
        {
            try
            {
                var collection = _database.GetCollection<T>(TableName);
                if (conditions != null)
                {
                    return collection.Find(conditions).ToList();
                }
                return collection.Find(_ => true).ToList();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
        }
        /// <summary>
        /// 根据查询条件，获取数据
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="TableName">数据表名称</param>
        /// <param name="Filter">查询条件</param>
        /// <param name="LimitNum">默认的限制条数，默认为100</param>
        /// <returns></returns>
        public List<T> GetList<T>(string TableName, FilterDefinition<T> Filter)
        {
            try
            {
                var collection = _database.GetCollection<T>(TableName);
                List<T> searchResult = collection.Find(Filter).ToList();//Limit(LimitNum)
                return searchResult;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }

        }
        #endregion

        #region INSERT
        /// <summary>
        /// 插入多条数据，数据用list表示
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public List<T> InsertMany<T>(List<T> list, string TableName)
        {
            var collection = _database.GetCollection<T>(TableName);
            collection.InsertMany(list);
            return list;
        }
        /// <summary>
        /// 插入单条数据
        /// </summary>
        /// <typeparam name="document"></typeparam>
        /// <param name="CollectionName"></param>
        /// <returns></returns>
        public void InsertOne<T>(T document, string CollectionName)
        {
            var collection = _database.GetCollection<T>(CollectionName);
            collection.InsertOne(document);
        }
        #endregion

        #region Delete
        /// <summary>
        /// 删除数据记录
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="list"></param>
        /// <returns></returns>
        public int DeleteMany<T>(string TableName, FilterDefinition<T> Filter)
        {
            try
            {
                var collection = _database.GetCollection<T>(TableName);
                DeleteResult deleteResult = collection.DeleteMany(Filter);
                return (int)deleteResult.DeletedCount;
            }
            catch (Exception ex)
            {
                return -1;
            }
        }
        #endregion

        
        /// <summary>
        /// 更新对象
        /// </summary>
        public int Update(string TableName, MongoDbTag mongoDbTag)
        {
            var collection = _database.GetCollection<MongoDbTag>(TableName);
            Expression<Func<MongoDbTag, bool>> filter = m => m.id == mongoDbTag.id;
            var updateDefinition = Builders<MongoDbTag>.Update
                                                       .Set(m => m.ts, mongoDbTag.ts)
                                                       .Set(p => p.value, mongoDbTag.value)
                                                       .Inc(p => p.device_name, mongoDbTag.device_name);

            var updateOptions = new UpdateOptions { IsUpsert = false };

            var t = collection.UpdateManyAsync(filter,updateDefinition,updateOptions);
            return (int)t.Result.ModifiedCount;
        }
    }
    /// <summary>
    /// 
    /// </summary>
    public class MongoDbTag
    {
        [BsonId]
        public ObjectId id { get; set; }
        /// <summary>
        /// deivce name信息
        /// </summary>
        [BsonElement("device_name")]
        public string device_name { get; set; }
        /// <summary>
        /// 值
        /// </summary>
        [BsonElement("value")]
        public object value { get; set; }
        /// <summary>
        /// 时间
        /// </summary>
        [BsonElement("ts")]
        public DateTime ts { get; set; } = DateTime.Now;
    }
}
